#include <REGX52.H>
#include <intrins.h>

/**
 * 4个楼层，楼层灯指示电梯位置，按键等待电梯到达
 * 横向4灯代表电梯要到达的楼层，按键按下对应楼层灯亮。
 * 程序需要记录当前电梯是上行还是下行。停靠对应楼层，让对应楼层灯闪烁。
 */

//电梯楼层指示灯
sbit LED1 = P2^0;  // 1楼指示灯
sbit LED2 = P2^1;  // 2楼指示灯
sbit LED3 = P2^2;  // 3楼指示灯
sbit LED4 = P2^3;  // 4楼指示灯

//电梯按钮
sbit firstFloor_up = P1 ^ 0;
sbit secondFloor_up = P1 ^ 1;
sbit secondFloor_down = P1 ^ 2;
sbit thirdFloor_up = P1 ^ 3;
sbit thirdFloor_down = P1 ^ 4;
sbit fourthFloor_down = P1 ^ 5;

// 电梯状态
unsigned char currentFloor = 1;       // 当前楼层
unsigned char elevatorDirection = 0;  // 电梯方向：0-上行，1-下行
unsigned char elevatorState = 0;      // 电梯状态：0-运行，1-停靠
unsigned char floorRequests[5] = {0}; // 楼层请求数组，索引1-4对应4个楼层

// 延时函数
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 123; j++)
        ;
}

// 检测楼层选择按键
void checkFloorButtons() {
    if(firstFloor_up == 0) {  
        delay_ms(20);  
        if(firstFloor_up == 0) {
            floorRequests[1] = 1;  // 标记1楼请求
            while(firstFloor_up == 0); 
        }
    }
    
    if(secondFloor_up == 0 || secondFloor_down = 0) {
        delay_ms(20);
        if(secondFloor_up == 0 || secondFloor_down = 0) 
        floorRequests[2] = 1;  
        while(secondFloor_up == 0 || secondFloor_down = 0);
    }
    
    if(thirdFloor_up == 0 || thirdFloor_down == 0) {
        delay_ms(20);
        if(thirdFloor_up == 0 || thirdFloor_down = 0) {
            floorRequests[3] = 1;
            while(thirdFloor_up == 0 || thirdFloor_down == 0);
        }
    }
    
    if(fourthFloor_down == 0) {
        delay_ms(20);
        if(fourthFloor_down == 0) {
            floorRequests[4] = 1;
            while(fourthFloor_down == 0);
        }
    }
}


//更新电梯位置显示+++++++++++++++++++++++++++++++++++++++++++++++++++
void updateElevatorDisplay() {
    //清除所有楼层指示灯
    LED1 = 1;
    LED2 = 1;
    LED3 = 1;
    LED4 = 1;
    
    //根据当前楼层点亮对应指示灯
    switch(currentFloor) {
        case 1: LED1 = 0; break;
        case 2: LED2 = 0; break;
        case 3: LED3 = 0; break;
        case 4: LED4 = 0; break;
    }
    
}

// 更新请求楼层显示++++++++++++++++++++++++++++++++++++++++++++
void updateRequestDisplay() {
    P0 = (P0 & 0xF0) | (floorRequests[1] << 0) | (floorRequests[2] << 1) | 
         (floorRequests[3] << 2) | (floorRequests[4] << 3);
}

// 电梯移动逻辑
void moveElevator() {
    if(elevatorState == STOPAT) {
        // 电梯正在停靠，不移动
        return;
    }
    
    // 如果没有请求，电梯待机
    if(!floorRequests[1] && !floorRequests[2] && !floorRequests[3] && !floorRequests[4]) {
        return;
    }
    
    // 处理上行情况
    if(elevatorDirection == ELEVATOR_UP) {
        // 检查当前楼层是否有请求
        if(floorRequests[currentFloor]) {
            elevatorState = STOPAT;  // 停靠当前楼层
            floorRequests[currentFloor] = 0;  // 清除请求
            return;
        }
        
        // 查找更高楼层的请求
        unsigned char i;
        for(i = currentFloor + 1; i <= 4; i++) {
            if(floorRequests[i]) {
                currentFloor++;  // 移动到下一层
                return;
            }
        }
        
        // 如果没有更高楼层的请求，改变方向为下行
        elevatorDirection = ELEVATOR_DOWN;
    }
    // 处理下行情况
    else {
        // 检查当前楼层是否有请求
        if(floorRequests[currentFloor]) {
            elevatorState = STOPAT;  // 停靠当前楼层
            floorRequests[currentFloor] = 0;  // 清除请求
            return;
        }
        
        // 查找更低楼层的请求
        unsigned char i;
        for(i = currentFloor - 1; i >= 1; i--) {
            if(floorRequests[i]) {
                currentFloor--;  // 移动到下一层
                return;
            }
        }
        
        // 如果没有更低楼层的请求，改变方向为上行
        elevatorDirection = ELEVATOR_UP;
    }
}

// 电梯停靠逻辑（闪烁效果）
void elevatorStop() {
    unsigned char i;
    for(i = 0; i < 5; i++) {  // 闪烁5次
        switch(currentFloor) {
            case 1: LED1 = ~LED1; break;
            case 2: LED2 = ~LED2; break;
            case 3: LED3 = ~LED3; break;
            case 4: LED4 = ~LED4; break;
        }
        delay_ms(300);
    }
    
    // 停止闪烁，保持点亮状态
    switch(currentFloor) {
        case 1: LED1 = 0; break;
        case 2: LED2 = 0; break;
        case 3: LED3 = 0; break;
        case 4: LED4 = 0; break;
    }
    
    // 恢复运行状态
    elevatorState = 0;
}

void main() {
    // 初始化IO口
    P0 = 0xFF;  // 输入模式
    P1 = 0xFF;  // 输入模式
    P2 = 0xFF;  // 输出模式
    P3 = 0xFF;  // 输出模式
    
    // 初始化电梯状态
    currentFloor = 1;
    elevatorDirection = ELEVATOR_UP;
    elevatorState = 0;
    
    // 初始化显示
    updateElevatorDisplay();
    updateRequestDisplay();
    
    while(1) {
        // 检测按键请求
        checkFloorButtons();
        checkDirectionButtons();
        
        // 更新请求显示
        updateRequestDisplay();
        
        // 处理电梯移动
        if(elevatorState == STOPAT) {
            elevatorStop();  // 处理停靠逻辑
        } else {
            moveElevator();  // 处理移动逻辑
            updateElevatorDisplay();  // 更新电梯位置显示
        }
        
        // 短暂延时，降低CPU使用率
        delay_ms(100);
    }
}